package com.functest.orm

import com.functest.util.CodeBased

/**
 * @author: DavydovMD
 * Date: 04.04.13
 * Time: 18:45
 */
class MapperUtil {
    @Singleton
    static class Transformations {
        /*
         {Field f, Map map ->
                assert f.from.size()==1
                return [(f.name): map[f.from.last()]]  as Map
            }
        */

        Closure _default() {
            com.functest.util.AnnotatedClosure.annotate('AsIs') { Field f, Map map ->
                assert f.from.size() == 1
                map[f.from.last()]
            }
        }

        Closure codeBasedEnum(Class<? extends CodeBased> clazz) {
            com.functest.util.AnnotatedClosure.annotate("to${clazz.simpleName}(CodeBased)") { Field f, Map map ->
                assert f.from.size() == 1
                Integer code = map[f.from.last()]
                //if (!code) return null    todo: think about null check
                def eVal = clazz.invokeMethod('fromCode', code)
                eVal
            }
        }

        Closure stringEnum(Class<? extends Enum> clazz) {
            com.functest.util.AnnotatedClosure.annotate("to${clazz.simpleName}(StringBased)") { Field f, Map map ->
                assert f.from.size() == 1
                String code = map[f.from.last()] as String
                clazz.invokeMethod('valueOf', code)
            }
        }

        Closure intToBool() {
            com.functest.util.AnnotatedClosure.annotate('transform intToBool') { Field f, Map map ->
                assert f.from.size() == 1
                int code = map[f.from.last()] as int
                code == 1
            }
        }

    }

    @Singleton
    static class TransformationsBack {
        Closure<Map> _default() {
            com.functest.util.AnnotatedClosure.annotate('AsIs') { Field f, def value ->
                (f.from.size() == 1) ? [(f.from.last()): value] as Map : [:]
            }
        }

        Closure codeBasedEnum(Class<? extends CodeBased> clazz) {
            com.functest.util.AnnotatedClosure.annotate("from${clazz.simpleName} (CodeBased)") { Field f, CodeBased value ->
                (f.from.size() == 1) ? [(f.from.last()): value.code as int] as Map : [:]
            }
        }

        Closure intToBool() {
            com.functest.util.AnnotatedClosure.annotate('transformBack: boolToInt') { Field f, def value ->
                (f.from.size() == 1) ? [(f.from.last()): value ? 1 : 0] as Map : [:]
            }
        }

        Closure stringEnum(Class<? extends Enum> clazz) {
            com.functest.util.AnnotatedClosure.annotate("from${clazz.simpleName} (StringBased)") { Field f, def value ->
                assert value.getClass() == clazz
                (f.from.size() == 1) ? [(f.from.last()): value.toString()] as Map : [:] as Map
            }
        }
    }

    static transform = Transformations.instance
    static transformBack = TransformationsBack.instance


}
